package com.example.pets_java.controller;

import com.example.pets_java.pojo.ChatMessage;
import com.example.pets_java.pojo.PetChat;
import com.example.pets_java.pojo.Pet;
import com.example.pets_java.pojo.PetDiary;
import com.example.pets_java.service.PetChatService;
import com.example.pets_java.service.PetService;
import com.example.pets_java.utils.SignatureUtil;
import com.example.pets_java.utils.JwtUtils;
import com.example.pets_java.mapper.PetDiaryMapper;
import com.example.pets_java.mapper.PetMapper;
import io.jsonwebtoken.Claims;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/api/chat")
public class PetChatController {

    private final PetChatService petChatService;
    private final PetService petService;
    private final WebClient webClient;
    private final SignatureUtil signatureUtil;
    private final PetDiaryMapper petDiaryMapper;
    private final PetMapper petMapper;

    @Autowired
    public PetChatController(PetChatService petChatService, PetService petService, WebClient webClient, SignatureUtil signatureUtil, PetDiaryMapper petDiaryMapper, PetMapper petMapper) {
        this.petChatService = petChatService;
        this.petService = petService;
        this.webClient = webClient;
        this.signatureUtil = signatureUtil;
        this.petDiaryMapper = petDiaryMapper;
        this.petMapper = petMapper;
    }

    @GetMapping("/pet/{petId}")
    public List<PetChat> getChatsByPetId(@PathVariable int petId) {
        return petChatService.getChatsByPetId(petId);
    }

    @PostMapping("/add")
    public void addChat(@RequestBody PetChat petChat) {
        petChatService.addChat(petChat);
    }

    @PostMapping("/send")
    public Mono<ResponseEntity<String>> sendMessage(@RequestBody ChatMessage message, @RequestHeader("Authorization") String token) {
        int userId = getUserIdFromToken(token);
        Pet pet = petService.getPetById(message.getPetId());

        if (pet == null || pet.getOwnerId() != userId) {
            return Mono.just(ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Pet not found for user"));
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String birthdate = dateFormat.format(pet.getBirthdate());

        String prompt = String.format("请你模仿我的宠物和我对话，宠物名字是 %s, 是%s. 喜欢的事物是 %s。出生日期是：%s。我们的相处细节有： %s,%s",
                pet.getName(), pet.getType(), pet.getLikes(), birthdate, pet.getDetails(), message.getContent());

        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("requestId", UUID.randomUUID().toString());

        MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
        queryParams.forEach((key, value) -> multiValueMap.add(key, value));

        return webClient.post()
                .uri(uriBuilder -> uriBuilder.path("/vivogpt/completions")
                        .queryParams(multiValueMap)
                        .build())
                .headers(headers -> headers.setAll(signatureUtil.generateAuthHeaders("POST", "/vivogpt/completions", queryParams)))
                .bodyValue(buildRequestBody(message, prompt))
                .retrieve()
                .bodyToMono(String.class)
                .map(body -> ResponseEntity.ok().body(body))
                .onErrorResume(e -> {
                    e.printStackTrace();
                    return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing your request: " + e.getMessage()));
                });
    }

    @PostMapping("/generateDiary/{petId}")
    public Mono<ResponseEntity<String>> generateDiary(@PathVariable int petId, @RequestHeader("Authorization") String token) {
        int userId = getUserIdFromToken(token);
        Pet pet = petMapper.findById(petId);
        if (pet == null || pet.getOwnerId() != userId) {
            return Mono.just(ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Pet not found or does not belong to user"));
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String birthdate = dateFormat.format(pet.getBirthdate());

        List<String> prompts = Arrays.asList(
                "今天去哪里玩了",
                "今天吃了什么好吃的",
                "请主人放心",
                "很想主人，但是自己过的很好",
                "今天交了什么新朋友",
                "今天在宠物学校学习了什么",
                "今天有乖乖的没有闯祸"
        );

        String prompt = String.format("以宠物的口吻向它的主人写一篇宠物日记。请注意，宠物现在独自生活，和主人不在一起，所以日记不要描述和主人之间的互动。请用第一人称，发挥创造力和想象力，编写一些小故事，但不要涉及具体日期。宠物名字是 %s, 是%s. 喜欢的事物是 %s。出生日期是：%s。我们的相处细节有： %s。%s",
                pet.getName(), pet.getType(), pet.getLikes(), birthdate, pet.getDetails(), prompts.get(new Random().nextInt(prompts.size())));

        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("requestId", UUID.randomUUID().toString());

        MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
        queryParams.forEach((key, value) -> multiValueMap.add(key, value));

        return webClient.post()
                .uri(uriBuilder -> uriBuilder.path("/vivogpt/completions")
                        .queryParams(multiValueMap)
                        .build())
                .headers(headers -> headers.setAll(signatureUtil.generateAuthHeaders("POST", "/vivogpt/completions", queryParams)))
                .bodyValue(buildRequestBody(new ChatMessage(), prompt))
                .retrieve()
                .bodyToMono(String.class)
                .flatMap(body -> {
                    String formattedBody = formatDiaryResponse(body);
                    PetDiary diary = new PetDiary();
                    diary.setPetId(petId);
                    diary.setEntry(formattedBody);
                    petDiaryMapper.insert(diary);
                    return Mono.just(ResponseEntity.ok().body(formattedBody));
                })
                .onErrorResume(e -> {
                    e.printStackTrace();
                    return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing your request: " + e.getMessage()));
                });
    }

    @GetMapping("/diaries/{petId}")
    public ResponseEntity<List<PetDiary>> getDiaries(@PathVariable int petId, @RequestHeader("Authorization") String token) {
        int userId = getUserIdFromToken(token);
        Pet pet = petMapper.findById(petId);
        if (pet == null || pet.getOwnerId() != userId) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
        List<PetDiary> diaries = petDiaryMapper.findByPetId(petId);
        return ResponseEntity.ok(diaries);
    }

    private String buildRequestBody(ChatMessage message, String prompt) {
        return String.format("{\"prompt\": \"%s\", \"model\": \"vivo-BlueLM-TB\", \"sessionId\": \"%s\"}",
                prompt, message.getSessionId());
    }

    private int getUserIdFromToken(String token) {
        String authToken = token.replace("Bearer ", "");
        Claims claims = JwtUtils.parseJWT(authToken);
        return (int) claims.get("userId");
    }

    private String formatDiaryResponse(String responseBody) {
        String formattedResponse = "未知内容";
        try {
            JSONObject jsonObject = new JSONObject(responseBody);
            if (jsonObject.has("data")) {
                JSONObject dataObject = jsonObject.getJSONObject("data");
                if (dataObject.has("content")) {
                    formattedResponse = dataObject.getString("content");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return formattedResponse;
    }
}
